package modes

import (
	"fmt"
	"time"
)

type Class struct {
	Id        int64        `json:"class_id" xorm:"id"`                 // 学员ID
	Phone     int64        `json:"class_phone" xorm:"phone"`           // 手机号
	Cid       int64        `json:"class_cid" xorm:"cid"`               // 班型id
	CName     string       `json:"class_cname" xorm:"cname"`           // 班型名称
	OrderNo   string       `json:"class_order_no" xorm:"order_no"`     // 单号
	RealPrice int64        `json:"class_real_price" xorm:"real_price"` // 价格
	At        int64        `json:"class_at" xorm:"at"`                 // 时间
	State     int64        `json:"class_state" xorm:"state"`           // 状态
	CloseAt   int64        `json:"class_close_at" xorm:"close_at"`     // 班的关闭时间
	Course    []JoinCourse `json:"course" xorm:"-"`
}
type PhoneClass struct {
	CId   int64      `json:"cid"`
	CName string     `json:"cname"`
	Sub   []CSubject `json:"subject"`
}
type CSubject struct {
	KId   int64  `json:"k_id" xorm:"-"`
	KName string `json:"k_name" xorm:"-"`
}

func (this *Class) TableName() string {
	return "user_class"
}
func (this *Class) Save() (int64, error) {
	this.At = time.Now().Unix()
	return Db(0).Insert(this)
}

func (this *Class) SetPhone(field string) (int64, error) {
	where := fmt.Sprintf("phone = %d", this.Phone)
	return this.update(where, field)
}

func (this *Class) SGet(phone int64) ([]Class, error) {
	swhere := fmt.Sprintf("phone = %d", phone)
	return this.where(1, 100, 0, swhere, "")
}

func (this *Class) Get() (bool, error) {
	return Db(0).Get(this)
}
func (this *Class) delete(where string) (int64, error) {
	return Db(0).Where(where).Delete(this)
}
func (this *Class) Del() (int64, error) {
	where := fmt.Sprintf("id =%d", this.Id)
	return this.delete(where)
}
func (this *Class) Count(where string) (int64, error) {
	var val Class
	return Db(0).Where(where).Count(&val)
}
func (this *Class) update(where string, field string) (int64, error) {
	return Db(0).Where(where).Cols(field).Update(this)
}

func (this *Class) IdSet(field string) (int64, error) {
	where := fmt.Sprintf("id = %d", this.Id)
	return this.update(where, field)
}

func (this *Class) GetPhone(phone int64) ([]Class, error) {
	list := make([]Class, 0)
	w := fmt.Sprintf("phone = %d", phone)
	err := Db(0).Where(w).Find(&list)
	return list, err
}

func (this *Class) GetCIdListByPhone(phone int64) ([]int, error) {
	list := make([]int, 0)
	w := fmt.Sprintf("phone = %d and state=0", phone)
	err := Db(0).Table("user_class").Select("cid").Where(w).Find(&list)
	return list, err
}

func (this *Class) where(fage, count, page int, where, field string) ([]Class, error) {
	list := make([]Class, 0)
	var err error
	if field == "" {
		field = "id"
	}
	if 0 == fage { // 从小到大排序
		err = Db(0).Where(where).
			Asc(field).
			Limit(count, page*count).
			Find(&list)
	} else { // 从大到小排序
		err = Db(0).Where(where).
			Desc(field).
			Limit(count, page*count).
			Find(&list)
	}
	return list, err
}
func (this *Class) List(val *Pager) error {
	val.TName = this.TableName()
	sAt := time.Now().Unix()
	w := fmt.Sprintf("phone = %d and state = 0 and close_at > %d", this.Phone, sAt)
	val.Total, _ = this.Count(w)
	list, err := this.where(val.Rules, val.Count, val.Page-1, w, "")
	if err == nil {
		val.List = list
	}
	return err
}
func (this *Class) CouserList() ([]PhoneClass, error) {
	var err error
	sil_class := make([]Class, 0) // 班
	sil_list := make([]PhoneClass, 0)

	w := fmt.Sprintf("cid = %d and phone = %d ", this.Cid, this.Phone)
	if err := Db(0).Where(w).Find(&sil_class); err != nil {
		return sil_list, err
	}
	for i, _ := range sil_class {

		var val PhoneClass
		val.CId = sil_class[i].Cid
		val.CName = sil_class[i].CName

		val.Sub, _ = this.GetCourse(val.CId)
		sil_list = append(sil_list, val)
	}
	fmt.Println("----------------------", sil_list)
	return sil_list, err
}

func (this *Class) ClassList() ([]PhoneClass, error) {
	var err error
	sil_class := make([]Class, 0) // 班
	sil_list := make([]PhoneClass, 0)
	sAt := time.Now().Unix()
	w := fmt.Sprintf("phone = %d and  close_at > %d ", this.Phone, sAt)
	if err := Db(0).Where(w).Find(&sil_class); err != nil {
		return sil_list, err
	}
	for i, _ := range sil_class {

		var val PhoneClass
		val.CId = sil_class[i].Cid
		val.CName = sil_class[i].CName

		val.Sub, _ = this.GetCourse(val.CId)
		sil_list = append(sil_list, val)
	}
	fmt.Println("----------------------", sil_list)
	return sil_list, err
}

func (this *Class) GetCourse(cid int64) ([]CSubject, error) {
	sil_csub := make([]CSubject, 0)
	var val SubClass
	var sub Subject
	tval := make([]int64, 0)
	slist, err := val.PIdList(cid)
	if nil == err {
		for _, row := range slist {
			tval = append(tval, row.SId-(row.SId%100000))
		}
	}
	tval = RemoveRepeatedElement(tval)
	if list, err := sub.GetName(tval); nil == err {
		for _, v := range list {
			sil_csub = append(sil_csub, CSubject{v.Id, v.Name})
		}
	}
	fmt.Println("+++++++++++++++", sil_csub)
	return sil_csub, err
}

func GetKname(kid int64) string {
	var val Subject
	w := fmt.Sprintf("id = %d", kid)
	_, err := Db(0).Where(w).Get(&val)
	if err != nil {
		fmt.Println(err.Error())
		return "-"
	}
	return val.Name
}

func RemoveRepeatedElement(arr []int64) (newArr []int64) {
	newArr = make([]int64, 0)
	for i := 0; i < len(arr); i++ {
		repeat := false
		for j := i + 1; j < len(arr); j++ {
			if arr[i] == arr[j] {
				repeat = true
				break
			}
		}
		if !repeat {
			newArr = append(newArr, arr[i])
		}
	}
	return
}

func (this *Class) Lists(phone int64) ([]Class, error) {
	swhere := fmt.Sprintf("phone = %d", phone)
	return this.where(1, 10, 0, swhere, "")
}

func (this *Class) GetListByIdList(idList []int64) ([]Class, error) {
	list := make([]Class, 0)
	err := Db(0).Table("user_class").In("id", idList).Limit(100).Find(&list)
	return list, err
}

func (this *Class) GetClass() (bool, error) {
	where := fmt.Sprintf("cid = %d and order_no = '%s'", this.Cid, this.OrderNo)
	return Db(2).Where(where).Get(this)
}

func (this *Class) ClassCid(phone int64) ([]int64, error) {
	swhere := fmt.Sprintf("phone  = %d ", phone)
	dl := []int64{}
	return dl, Db(0).Table("user_class").Cols("cid").Where(swhere).Limit(100).Find(&dl)
}
